package com.sdp.wx.controller;


import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sdp.core.bizc.db.Query;
import com.sdp.core.bizc.utils.ApplicationContextUtils;
import com.sdp.core.bizc.utils.UniqueCheckTools;
import com.sdp.core.bizc.vo.BusinessContext;
import com.sdp.core.bizc.vo.DataCenter;
import com.sdp.core.bizc.vo.Result;
import com.sdp.flow.db.entity.ActHiComment;
import com.sdp.flow.db.service.IWorkflowService;
import com.sdp.flow.dto.FlowParam;
import com.sdp.flow.utils.FlowConstants;
import com.sdp.wx.db.wx_contract.entity.WxContract;
import com.sdp.wx.db.wx_contract.service.IWxContractService;
import com.sdp.wx.db.wx_contract_detail.service.IWxContractDetailService;
import com.sdp.wx.utils.CurrentLoginEmp;
import com.sdp.wx.utils.WxConstants;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zsp
 * @since 2024-01-05
 */
@RestController
@RequestMapping("/WxContractController")
public class WxContractController {

	
	@Autowired
	private Query query;
	
	@Autowired
	private IWxContractService iWxContractService;
	
	@Autowired
	private IWxContractDetailService iWxContractDetailService;
	
	@Autowired
	private UniqueCheckTools uniqueCheckTools;
	
	@Autowired
	private CurrentLoginEmp currentLoginEmp;
	
	@Autowired
	private IWorkflowService workflowService;
	
	@PostMapping(value = "/page")
	public Result<?> page(@RequestBody DataCenter dataCenter) {
		return Result.ok(query.page(iWxContractService, WxContract.class, dataCenter));
	}
	
	@PostMapping(value = "/save")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> save(@RequestBody WxContract contract) {
		if(contract==null) {
			return Result.error("合同信息为空");
		}
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		if(StringUtils.isEmpty(contract.getKeyId())) {
			Result<?> r = uniqueCheckTools.isUniqueSingle(iWxContractService, WxContract.class, new String[] {"contractCode"}, "keyId", contract, null, false);
			if(r==null || !r.isSuccess()) {
				return Result.error("合同编号不能重复");
			}
			contract.setCreateTime(LocalDateTime.now());
			contract.setIsFinish(WxConstants.否.getCode());
			contract.setIsRepair(WxConstants.否.getCode());
			contract.setApprovalState(WxConstants.流程审批状态_未提交.getCode());
			contract.setApplicationEmpNo(emp.getString("empNo"));
			contract.setApplicationEmpName(emp.getString("empName"));
			iWxContractService.save(contract);
		}else {
			Result<?> r = uniqueCheckTools.isUniqueSingle(iWxContractService, WxContract.class, new String[] {"contractCode"}, "keyId", null, contract, false);
			if(r==null || !r.isSuccess()) {
				return Result.error("合同编号不能重复");
			}
			iWxContractService.updateById(contract);
		}
		
		return Result.ok();
	}
	
	@PostMapping(value = "/saveAndStartFlow")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> saveAndStartFlow(@RequestBody WxContract contract) {
		if(contract==null) {
			return Result.error("合同信息为空");
		}
		Result<?> r = ApplicationContextUtils.getBean(WxContractController.class).save(contract);
		if(r==null || !r.isSuccess()) {
			return r;
		}
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		contract.setTemplateId(WxConstants.合同审批流程模板.getCode());
		//设置审批状态
		contract.setApprovalState(WxConstants.流程审批状态_审批中.getCode());
		
		//发起流程
		FlowParam flowParam = new FlowParam();
		flowParam.setUserId(emp.getString("empNo"));
		flowParam.setTemplateId(contract.getTemplateId());
		flowParam.setBizId(contract.getKeyId());
		
		//指定审批人
		Map<String, Object> variableMap = new HashMap<>();
		BusinessContext businessContext = new BusinessContext();
		businessContext.put(WxContract.class, contract);
		variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, contract.getApprover());
		variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxContractController");
		variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowCommitListener");
		variableMap.put(WxConstants.流程监听器中执行类的方法的参数.getCode(), businessContext);
		flowParam.setVariableMap(variableMap);
		
		
		String instanceId = workflowService.startFlowAndCommit(flowParam);
		if (StringUtils.isEmpty(instanceId)) {
			return Result.error("流程启动失败!");
		}
		
		//发起成功设置流程实例Id
		contract.setInstanceId(instanceId);
		iWxContractService.updateById(contract);
		return Result.ok(contract);
		
		
	}
	
	/**
	 * 流程提交
	 * @param contract
	 * @return
	 */
	@PostMapping(value = "/commit")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> commit(@RequestBody WxContract contract) {
		if(contract == null) {
			return Result.error("合同信息为空");
		}
		if (StringUtils.isEmpty(contract.getKeyId())) {
			return Result.error("合同信息内码为空");
		}
		
		JSONObject emp = currentLoginEmp.getCurrentEmpInfo();
		//提交流程
		if (StringUtils.isEmpty(contract.getTaskId())) {
			return Result.error("合同审批信息不完整");
		}
		FlowParam flowParam = new FlowParam();
		flowParam.setUserId(emp.getString("empNo"));
		
		flowParam.setTaskId(contract.getTaskId());
		if (!StringUtils.isEmpty(contract.getIsPass())) {
			Map<String, Object> variableMap = new HashMap<>();
			variableMap.put("isPass", contract.getIsPass());
			variableMap.put("link", contract.getLink());
			variableMap.put("userName", emp.getString("empName"));
			variableMap.put("userAvatar", emp.getString("profilePicture"));
			variableMap.put("userSign", emp.getString("nameSign"));
			BusinessContext businessContext = new BusinessContext();
			businessContext.put(WxContract.class, contract);
			
			String currentNode = workflowService.getCurrentNode(contract.getTaskId());
			if((WxConstants.是.getCode().equals(contract.getIsPass()) && WxConstants.合同审批流程_最后审批节点名称.getCode().equals(currentNode)) ||(FlowConstants.flow_end_value.equals(contract.getLink()))) {
				//如果节信息是结束
				//或者最后一个环节，没有环节信息，并且是同意通过
				variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxContractController");
				variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowEndListener");
			}else {
				variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxContractController");
				variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowCommitListener");
			}
			variableMap.put(WxConstants.流程监听器中执行类的方法的参数.getCode(), businessContext);
			
			
			if (WxConstants.否.getCode().equals(contract.getIsPass())) {
				variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, contract.getApplicationEmpNo());
				if(StringUtils.isEmpty(contract.getApprovalOpinion())){
					contract.setApprovalOpinion("不同意");
				}
				contract.setApprovalState(WxConstants.流程审批状态_驳回.getCode());
			}else {
				if(StringUtils.isEmpty(contract.getApprovalOpinion()) && !WxConstants.合同审批流程_申报节点名称.getCode().equals(currentNode)){
					contract.setApprovalOpinion("同意");
				}
				variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, contract.getApprover());
				contract.setApprovalState(WxConstants.流程审批状态_审批中.getCode());
			}
			
			flowParam.setVariableMap(variableMap);
			
			//更新审批人列表
			if(!WxConstants.合同审批流程_申报节点名称.getCode().equals(currentNode)){
				contract.setApproversList((contract.getApproversList()==null?"":contract.getApproversList())+("["+emp.getString("empNo")+"]"));
			}
			
		
		}
		
		if (!StringUtils.isEmpty(contract.getApprovalOpinion())) {
			flowParam.setOpinion(contract.getApprovalOpinion());
		}
		iWxContractService.updateById(contract);
		workflowService.commitTask(flowParam);
		return Result.ok();
	}
	
	/**
	 * 流程撤销
	 * @param instanceId
	 * @return
	 */
	@GetMapping(value = "/cancel")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> cancel(@RequestParam(name="instanceId",required=true) String instanceId) {
		LambdaQueryWrapper<WxContract> query = new LambdaQueryWrapper<>();
		query.eq(WxContract::getInstanceId, instanceId);
		WxContract contract = iWxContractService.getOne(query);
		if(contract==null) {
			return Result.error("合同信息不存在，不能进行撤销");
		}
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		if(!contract.getApplicationEmpNo().equals(emp.getString("empNo"))) {
			return Result.error("不是合同提交人，不能进行撤销操作");
		}
		
		//流程撤销
		workflowService.stopFlow(instanceId, "撤销");
		
		//删除合同信息
		iWxContractService.removeById(contract.getKeyId());
		iWxContractDetailService.removeWxContractDetail(contract.getContractCode());
		return Result.ok();
	}
	
	public void flowCommitListener(BusinessContext businessContext) {
	
	}
	
	/**
	 * 审批结束后，更改审批状态
	 * @param businessContext
	 */
	@Transactional(rollbackFor=Exception.class)
	public void flowEndListener(BusinessContext businessContext) {
		WxContract contract = businessContext.get(WxContract.class);
		if(contract!=null && WxConstants.是.getCode().equals(contract.getIsPass())) {
			contract.setApprovalState(WxConstants.流程审批状态_审批通过.getCode());
			iWxContractService.updateById(contract);
		}
	}
	
	@RequestMapping(value="/queryByInstanceId")
	public Result<?> queryByInstanceId(@RequestParam String instanceId) {
		if (StringUtils.isEmpty(instanceId)) {
			return Result.error("instanceId不能为空!");
		}
		QueryWrapper<WxContract> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(WxContract::getInstanceId, instanceId);
		WxContract contract = iWxContractService.getOne(queryWrapper, false);
		List<ActHiComment> commentList = workflowService.getApprovedOpinionNew(instanceId);
		contract.setApprovalOpinions(commentList);
		return Result.ok(contract);
	}
}

